package cn.cz.collector.controller;

import io.prometheus.client.Counter;
import io.prometheus.client.Gauge;
import io.prometheus.client.Histogram;
import io.prometheus.client.Summary;
import io.prometheus.client.exporter.PushGateway;
import io.swagger.annotations.Api;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import java.io.IOException;

/**
 * @author chengzhen
 * @date 2021/3/24
 * @time 2:28 下午
 * 通过推送到pushGateWay推送到prometheus
 */
@RestController
@RequestMapping("/v1/api")
@Api(tags = "app2PushGateway2Prometheus", description = "应用推送指标到pushGateWay, 由pushGateWay推送到prometheus")
public class PushGateWayController {

    @Value("${pushgateway.server.address}")
    private String pushGateWayIp;

    private static final PushGateway pushway = new PushGateway("172.16.6.251:9091");

    /*
     *  使用Counter.build()创建Counter类型的监控指标，并且通过name()方法定义监控指标的名称network_traffic_input
     * ，通过labelNames()定义该指标包含的标签。最后通过register()将该指标注册到Collector的defaultRegistry中
     */
    static final Counter counterDemo = Counter.build()
            .name("pushgateway_counterChanger2").labelNames("wy","zxjr","ocs","xxjf","unit")
            .help("Counter 实例").register();

    //指标埋点，定时器会造成普罗米修斯与本地的数据时间戳不同步，尽量不要使用这种方式，实例中的定时器是为了数据演示
    @Scheduled(cron="0/5 * * * * ?")
    @RequestMapping("/changeCounter")
    public  void changeCounter() {
        try {
            counterDemo.labels("网元", "在线接入", "OCS", "消息计费", "seconds").inc();//指标值增加
            pushway.push(counterDemo, "pushgateway_job");
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

    /**指标注册
     * name设置指标名
     * labelNames设置各项指标名称
     * help设置指标描述
     */
    static final Gauge gaugeDemo = Gauge.build()
            .name("pushgateway_gaugeDemo")
            .labelNames("label1","label2","label3","label4","label5")
            .help("gauge 实例").register();

    //指标埋点
    @Scheduled(cron="0/5 * * * * ?")
    @RequestMapping("/changeGauge")
    public  void  changeGauge() {
        gaugeDemo.labels("1","2","3","4","5").inc(); //指标值加1
        gaugeDemo.labels("1","2","3","4","5").dec(); //指标值减一
        gaugeDemo.labels("1","2","3","4","5").set(19.00); //指标值直接赋值
        try {
            pushway.push(gaugeDemo, "pushgateway_job");
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

    /**
     * 注册
     * 注册时buckets()设置区间值，如下设置了100、200、300三个区间值
     */
    static final Histogram histogramDemo = Histogram.build()
            .labelNames("label1", "label2", "label3", "label4", "label5")
            .name("histogramDemo")
            .buckets(100, 200, 300)
            .help("Histogram 实例")
            .register();

    //指标埋点
    @Scheduled(cron = "0/5 * * * * ?")
    public void changeHistogram()
    {
        /**
         * 本次执行的指标值
         * 如下设置为150，则每次执行，小于200区间以及小于300区间加1，小于100区间不变
         */
        histogramDemo.labels("1", "2", "3", "4", "5").observe(150);
        try {
            pushway.push(histogramDemo, "pushgateway_job");
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

    //注册
    static final Summary summaryDemo = Summary.build()
            .quantile(0.5, 0.01)   // 添加50%分位数，允许有5%的误差,相当于求中位数
            .quantile(0.9, 0.01)   // 添加90%分位数，允许有1%的误差
            .name("summaryDemo").labelNames("label1","label2","label3","label4","label5")
            .help("Summary 实例").register();
    //指标埋点
    @Scheduled(cron="0/5 * * * * ?")
    public  void  changeSummary(){
        summaryDemo.labels("1","2","3","4","5").observe(1);
        try {
            pushway.push(summaryDemo, "pushgateway_job");
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

}
